/* adlist.h - A generic doubly linked list implementation
 *
 * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of Redis nor the names of its contributors may be used
 *     to endorse or promote products derived from this software without
 *     specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __ADLIST_H__
#define __ADLIST_H__

/* Node, List, and Iterator are the only data structures used currently. */

typedef struct listNode {
    struct listNode *prev;//前置节点
    struct listNode *next;//后置节点
    void *value; //节点值
} listNode;

typedef struct listIter {
    listNode *next;
    int direction; //迭代方向：头部/尾部 宏定义：AL_START_HEAD头  AL_START_TAIL尾
} listIter;

//list用来持有链表 
typedef struct list {
    listNode *head; //连表头节点
    listNode *tail;//链表尾节点
    void *(*dup)(void *ptr); //？节点值复制函数
    void (*free)(void *ptr);//节点值释放函数
    int (*match)(void *ptr, void *key); //节点值对比函数
    unsigned long len; //链表的节点数量
} list;

/* Functions implemented as macros */
#define listLength(l) ((l)->len)
#define listFirst(l) ((l)->head)
#define listLast(l) ((l)->tail)
#define listPrevNode(n) ((n)->prev)
#define listNextNode(n) ((n)->next)
#define listNodeValue(n) ((n)->value)

#define listSetDupMethod(l,m) ((l)->dup = (m))
#define listSetFreeMethod(l,m) ((l)->free = (m))
#define listSetMatchMethod(l,m) ((l)->match = (m))

#define listGetDupMethod(l) ((l)->dup)
#define listGetFree(l) ((l)->free)
#define listGetMatchMethod(l) ((l)->match)

/* Prototypes */
list *listCreate(void); //创建一个不包含节点的空链表
void listRelease(list *list); //释放链表以及他的节点
void listEmpty(list *list); //只释放链表中的节点
list *listAddNodeHead(list *list, void *value);//从头部插入一个节点
list *listAddNodeTail(list *list, void *value);//从尾部插入一个节点
//从old_node节点插入一个值，after参数：是从old_node节点前插入还是后插入
list *listInsertNode(list *list, listNode *old_node, void *value, int after); 
void listDelNode(list *list, listNode *node); //删除节点
listIter *listGetIterator(list *list, int direction); //获取个节点的迭代器
listNode *listNext(listIter *iter); //获取节点的下一节点 ，iter觉得方向，从头部还是从尾部
void listReleaseIterator(listIter *iter);//释放迭代器
list *listDup(list *orig); //复制的链表
listNode *listSearchKey(list *list, void *key); //搜索节点
listNode *listIndex(list *list, long index); //
void listRewind(list *list, listIter *li); //重置迭代器 到头部
void listRewindTail(list *list, listIter *li);//重置迭代器 到尾部
void listRotate(list *list);//
void listJoin(list *l, list *o);

// 
/* Directions for iterators */
#define AL_START_HEAD 0  //迭代器迭代方向 从头往尾
#define AL_START_TAIL 1  //迭代器迭代方向 从尾往头

#endif /* __ADLIST_H__ */
